package com.lant.utils;

import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;
import com.lant.enums.ResponseStatusEnum;
import com.lant.exception.ErrorMsgException;
import com.lant.pojo.LantResult;
import com.lant.utils.HttpUtils;
/**
 * @description: Redis工具类
 * @projectName: lant-service-provider
 * @className: RedisUtil
 * @createTime: 2020年5月20日 下午5:19:10
 */
public class RedisUtil {

    private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);

    private static String REDIS_SERVER_HOST;

    private static final String SERVICE_EXCEPTION = "服务出现异常，请联系管理员%s";

    private RedisUtil() {
        super();
    }

    /**
     * @Title: setServerHost
     * @Description: 从非静态方法正确地更新静态字段非常困难，如果有多个类实例和/或多个线程在运行，则很容易导致错误。理想情况下，静态字段只能从同步的静态方法中更新。
     * @param: serverHost
     * @return: void
     * @author: YFL
     * @date: 2020年5月20日 下午5:12:42
     */
    public static void setServerHost(String serverHost) {
        RedisUtil.REDIS_SERVER_HOST = serverHost;
        logger.info("REDIS_SERVER_HOST = {}", serverHost);
    }

    /**
     * @Title: get
     * @Description: redis通过key获取value
     * @param: key
     * @return: LantResult
     * @date: 2020年4月29日 下午1:31:28
     */
    public static LantResult get(String key) {
        // 获取缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "/get");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: set
     * @Description: redis添加缓存
     * @param: key
     * @param: value
     * @return: LantResult
     * @date: 2020年4月29日 下午1:32:53
     */
    public static LantResult set(String key, String value) {
        // 添加缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("value", value);
        String redisHost = String.format(REDIS_SERVER_HOST, "/set");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: set
     * @Description: redis添加缓存和有效期
     * @param: key-键
     * @param: value-值
     * @param: second-秒
     * @return: LantResult
     * @date: 2020年4月29日 下午1:32:53
     */
    public static LantResult set(String key, String value, int second) {
        // 添加缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("value", value);
        params.put("second", second);
        String redisHost = String.format(REDIS_SERVER_HOST, "/setTime");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: hget
     * @Description: Hash操作 返回哈希表 key 中给定域 field 的值。
     * @param: hkey
     * @param: key
     * @return: LantResult 给定域的值
     * @date: 2020年4月29日 下午1:44:44
     */
    public static LantResult hget(String hkey, String key) {
        // 获取缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("hkey", hkey);
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "/hget");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: hset
     * @Description: Hash操作 设置字段值
     * @param: hkey
     * @param: key
     * @param: value
     * @return: LantResult如果 field 是哈希表中的一个新建域，并且值设置成功，返回 1；如果哈希表中域 field 已经存在且旧值已被新值覆盖，返回 0
     * @date: 2020年4月29日 下午1:43:52
     */
    public static LantResult hset(String hkey, String key, String value) {
        // 添加缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("hkey", hkey);
        params.put("key", key);
        params.put("value", value);
        String redisHost = String.format(REDIS_SERVER_HOST, "/hset");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: incr
     * @Description: Redis基本（字符串）操作 将 key 中储存的数字值增一。
     * @param: key 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 INCR 操作。 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
     * @return: LantResult
     * @date: 2020年4月29日 下午1:41:40
     */
    public static LantResult incr(String key) {
        // incr缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "/incr");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: expire
     * @Description: Redis基本（键）操作 设置某一记录的生存时间，过期删除
     * @param: key设置可挥发的key
     * @param: seconds超时时间，单位：秒
     * @return: LantResult
     * @date: 2020年4月29日 下午1:40:22
     */
    public static LantResult expire(String key, int seconds) {
        // expire缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("seconds", seconds);
        String redisHost = String.format(REDIS_SERVER_HOST, "/expire");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: ttl
     * @Description: Redis基本（键）操作 查看某个key的剩余生存时间:time to live
     * @param: key 当 key 不存在或没有设置生存时间时，返回 -1 。否则，返回 key 的剩余生存时间(以秒为单位)。
     * @return: LantResult
     * @date: 2020年4月29日 下午1:39:13
     */
    public static LantResult ttl(String key) {
        // ttl缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "/ttl");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: del
     * @Description: 从redis中根据key删除对象值
     * @param: key
     * @return: long
     * @date: 2020年4月29日 下午1:46:59
     */
    public static LantResult del(String key) {
        // del缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "/del");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }

    /**
     * @Title: hdel
     * @Description: Hash操作 删除哈希表中的一个字段，字段不存在将被忽略
     * @param: hkey
     * @param: key
     * @return: LantResult被成功移除的域的数量，不包括被忽略的域
     * @date: 2020年4月29日 下午1:45:49
     */
    public static LantResult hdel(String hkey, String key) {
        // hdel缓存
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> params = new HashMap<>();
        params.put("hkey", hkey);
        params.put("key", key);
        String redisHost = String.format(REDIS_SERVER_HOST, "hdel");
        LantResult result = HttpUtils.post(restTemplate, redisHost, "", params);

        // 查看接口调用是否正常
        if (result.getStatus().equals(ResponseStatusEnum.BAD_REQUEST.getValue())) {
            logger.error(String.format(SERVICE_EXCEPTION, result.getMsg()));
            throw new ErrorMsgException(String.format(SERVICE_EXCEPTION, result.getMsg()));
        }

        return result;
    }
}
